#include "Interp.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

/**
 * @brief Function F1 defines the mathematical function 1 / (1 + x^2).
 * 
 * @param x The input value to evaluate the function.
 * @return The result of evaluating F1(x).
 */
double F1(double x) {
    return 1.0 / (1.0 + x * x);
}

int main() {
    // Define values for n, representing the number of intervals for interpolation
    std::vector<int> ns = {2, 4, 6, 8};
    double a = -5; // Lower bound of the interval
    double b = 5;  // Upper bound of the interval
    
    // Perform interpolation for each specified n
    for (int n : ns) {
        std::vector<double> xValues; // Vector to store x values
        std::vector<double> yValues; // Vector to store corresponding y values
        double h = (b - a) / n; // Step size based on n intervals

        // Generate x and y values for interpolation
        for (int i = 0; i <= n; ++i) {
            double xi = a + i * h;
            xValues.push_back(xi);
            yValues.push_back(F1(xi));
        }

        // Create a Newton interpolation object with x and y values
        NewtonInterp interp(xValues, yValues);

        // Define output directory and filename
        const std::string output_dir = "output";
        std::string filename = "B_" + std::to_string(n) + ".txt";
        std::ofstream outfile(output_dir + "/" + filename);
        if (!outfile.is_open()) {
            std::cerr << "Failed to open " << filename << " for writing." << std::endl;
            return 1;
        }

        // Evaluate interpolation at points from -5 to 5 with a step of 0.01
        for (double x = -5; x <= 5; x += 0.01) {
            outfile << x << " " << interp.evaluate(x) << std::endl;
        }
    }

    return 0;
}
